<?php

namespace app\agent\model\order;

use think\facade\Db;
use think\facade\Request;
use app\common\model\Export;
use app\common\model\FinanceStat;

class Power
{
    private $table = 'power_order';
    private $servType = PRODUCT_POWER_SERV;

    /**
     * 列表.
     */
    public function getList($params)
    {
        $where = [];
        $where[] = ['agent_id', '=', $params['agent']['id']];
        $where[] = ['status', '=', 2];
        if (!empty($params['card_no'])) {
            $where[] = ['card_no', '=', $params['card_no']];
        }
        $orderId = trim($params['order_id'] ?? '');
        if ($orderId) {
            $where[] = ['sub_order_id|out_order_id|supplier_order_no', '=', $orderId];
        }
        if (!empty($params['card_type'])) {
            $where[] = ['card_type', '=', $params['card_type']];
        }
        if (!empty($params['supplier_status'])) {
            if (in_array($params['supplier_status'], [3, 4])) {
                $where[] = ['supplier_status', '=', $params['supplier_status']];
            } else {
                $where[] = ['supplier_status', 'in', [1, 2]];
            }
        }
        if (!empty($params['created_at'])) {
            $where[] = ['created_at', '>=', $params['created_at'][0]];
            $where[] = ['created_at', '<=', $params['created_at'][1] . ' 23:59:59'];
        }
        if (!empty($params['finish_time'])) {
            $where[] = ['finish_time', '>=', strtotime($params['finish_time'][0])];
            $where[] = ['finish_time', '<=', strtotime($params['finish_time'][1] . ' 23:59:59')];
        }
        $paginate = [
            'page' => $params['page'] ?? 1,
            'list_rows' => $params['list_rows'] ?? 10,
        ];
        $channelList = Db::name('agent_channel')
            ->field('id, name')
            ->where('agent_id', $params['agent']['id'])
            ->where('is_deleted', 0)
            ->order('name asc')
            ->select()
            ->toArray();
        $channel = array_column($channelList, 'name', 'id');

        $list = Db::name($this->table)
            ->where($where)
            ->order('id desc');

                // 导出数据字段处理
        if (!empty($params['is_export'])) {
            $list = $list->select()->toArray();
            $res = [];
            $title = ['系统订单号', '账号', '运营商', '充值金额', '销售价', '结算价', '利润', '订单状态', '订单来源', '下单时间', '完成时间', '备注'];
            $statusMap = [
                -1 => '代理商余额不足',
                1 => '充值中',
                2 => '充值中',
                3 => '充值成功',
                4 => '充值失败',
            ];
            $orderFromMap = [
                ORDER_FROM_H5 => 'H5',
                ORDER_FROM_API => 'API',
                ORDER_FROM_BATCH_IMPORT => '批量导入',
            ];
            foreach ($list as $v) {
                if ($v['finish_time']) {
                    $v['finish_time'] = date('Y-m-d H:i:s', $v['finish_time']);
                } else {
                    $v['finish_time'] = '';
                }
                $res[] = [
                    $v['order_id']."\t",
                    $v['card_no'],
                    $v['card_type'] == 1 ? '国家电网' : '南方电网',
                    fen2yuan($v['amount']).'',
                    fen2yuan($v['sale_price']).'',
                    fen2yuan($v['settle_price']).'',
                    fen2yuan($v['profit']).'',
                    $statusMap[$v['supplier_status']] ?? '充值中',
                    $orderFromMap[$v['order_from']],
                    $v['created_at'],
                    $v['finish_time'],
                    $v['remark'],
                ];
            }
            unset($list);
            $export = new Export;
            $name = '电费订单';
            return $export->downloadExcel($title, $res, $name);
        }

        $list = $list->paginate($paginate)->toArray();
        if ($list['data']) {
            foreach ($list['data'] as $k => $v) {
                $list['data'][$k]['channel_name'] = $channel[$v['channel_id']] ?? '';
                if ($v['finish_time']) {
                    $list['data'][$k]['finish_time'] = date('Y-m-d H:i:s', $v['finish_time']);
                } else {
                    $list['data'][$k]['finish_time'] = '';
                }
            }
        }
        $list['channelList'] = $channelList;
        $list['excel_url'] = Request::domain().'/downloadDemo/power.xlsx';

        return success('操作成功', $list);
    }

    /**
     * Excel 批量导入订单.
     */
    public function batchImport($data, $agentId)
    {
        // 校验是否有电费的权限
        $serviceConfig = Db::name('agent_service_config')
            ->where('agent_id', $agentId)
            ->where('serv_type', $this->servType)
            ->find();
        if (empty($serviceConfig) || $serviceConfig['status'] != 1) {
            return fail('你尚未开通电费充值权限，请联系商务进行开通');
        }
        if ($serviceConfig['value'] < 80) {
            return fail('电费充值权限配置有误，请联系商务进行修改');
        }

        $list = [];
        $orderNum = 0;
        $orderAmount = 0;

        $agent = Db::name('agent')
            ->where('id', $agentId)
            ->find();
        $settlePrice = 0;
        $settleDiscount = $serviceConfig['value'];

        // 获取供应商
        $supplierIds = Db::name('agent_supplier')
            ->where('agent_id', $agentId)
            ->where('serv_type', $this->servType)
            ->column('supplier_id');
        if (empty($supplierIds)) {
            return fail('通道维护中');
        }
        $supplier = Db::name('base_supplier')
            ->field('id, settle_value')
            ->whereIn('id', $supplierIds)
            ->where('serv_type', $this->servType)
            ->whereNull('deleted_at')
            ->select()
            ->toArray();
        if (empty($supplier)) {
            return fail('通道维护中。');
        }
        // 随机搞一个供应商
        $index = array_rand($supplier);
        $supplier = $supplier[$index];
        // 供应商折扣
        $rechargeSupplierConfig = Db::name('recharge_supplier_config')
            ->where('supplier_id', $supplier['id'])
            ->find();
        if (empty($rechargeSupplierConfig)) {
            return fail('供应商折扣配置有误');
        }

        foreach ($data as $k => $v) {
            $index = $k + 1;
            $v = array_map('trim', $v);
            if (empty($v['账号'])) {
                return fail('第 '.$index.' 个订单【账号】不能为空');
            }
            if (empty($v['充值金额'])) {
                return fail('第 '.$index.' 个订单【充值金额】不能为空');
            }
            // if (!in_array($v['充值金额'], [30, 50, 100, 200])) {
            //     return fail('第 '.$index.' 个订单充值金额 '.$v['充值金额'].' 有误。充值金额只能是 30/50/100/200');
            // }
            if (empty($v['运营商'])) {
                return fail('第 '.$index.' 个订单【运营商】不能为空');
            }
            if (!in_array($v['运营商'], ['国家电网', '南方电网'])) {
                return fail('第'.$index.'个订单【运营商】有误：'.$v['运营商']);
            }

            if (empty($v['省份'])) {
                return fail('第 '.$index.' 个订单【省份】不能为空');
            }
            if (empty($v['城市'])) {
                return fail('第 '.$index.' 个订单【城市】不能为空');
            }

            $list[] = [
                'card_no' => $v['账号'],
                'amount' => $v['充值金额'],
                'card_type' => $v['运营商'] == '国家电网' ? 1 : 2,
                'province' => $v['省份'],
                'city' => $v['城市'],
                'order_type' => 1, // 目前只有慢充
            ];
            ++$orderNum;
            $orderAmount += $v['充值金额'];

            $settlePrice += intval(strval($v['充值金额'] * $settleDiscount));
        }
        if (empty($list)) {
            return fail('没有可导入的数据');
        }
        if ($orderNum > 2000) {
            return fail('单次最多导入 2000 个订单');
        }

        if ($settlePrice > $agent['balance']) {
            return fail('账户余额不足，请先充值。当前余额 '.fen2yuan($agent['balance']).' 元');
        }

        $orderId = generateOrderId($this->servType, $this->table);
        if (false === $orderId) {
            return fail('订单号生成失败，请稍后重试');
        }

        $orderNum = 0;
        $orderAmount = 0;
        foreach ($list as $k => $v) {
            Db::startTrans();
            try {
                $settlePrice = intval(strval($v['amount'] * $settleDiscount));
                $balance = Db::name('agent')
                    ->where('id', $agentId)
                    ->value('balance');
                if ($balance < $settlePrice) {
                    throw new \Exception('账户余额不足：'.fen2yuan($balance));
                }

                // 供应商结算价
                $supplierPrice = intval(strval($v['amount'] * $rechargeSupplierConfig['slow_settle_value']));
                $platformProfit = $settlePrice - $supplierPrice;

                $subOrderId = $orderId.sprintf('%04d', $k);
                $id = Db::name('power_order')
                    ->insertGetId([
                        'agent_id' => $agentId,
                        'order_id' => $orderId,
                        'sub_order_id' => $subOrderId,
                        'card_no' => $v['card_no'],
                        'amount' => yuan2fen($v['amount']),
                        'card_type' => $v['card_type'],
                        'province' => $v['province'],
                        'city' => $v['city'],
                        'status' => 2,
                        'sale_discount' => $settleDiscount,
                        'settle_discount' => $settleDiscount,
                        'sale_price' => $settlePrice,
                        'settle_price' => $settlePrice,
                        'supplier_discount' => $rechargeSupplierConfig['slow_settle_value'], //供应商折扣
                        'supplier_price' => $supplierPrice,
                        'platform_profit' => $platformProfit, // 平台利润
                        'profit' => 0,  // 导入的订单，按结算价结算，代理商利润 0
                        'settle_type' => SETTLE_TYPE_PREPAY, // 预充
                        'order_type' => $v['order_type'],
                        'order_from' => ORDER_FROM_BATCH_IMPORT,
                        'supplier_id' => $supplier['id'],
                    ]);
                Db::name('agent')
                    ->where('id', $agentId)
                    ->dec('balance', $settlePrice)
                    ->update([
                        'balance_last_updated_at' => date('Y-m-d H:i:s'),
                    ]);
                Db::name('agent_balance_log')
                    ->insert([
                        'agent_id' => $agentId,
                        'type' => BALANCE_POWER_EXPENSE,
                        'amount' => -$settlePrice,
                        'old_balance' => $balance,
                        'new_balance' => $balance - $settlePrice,
                        'remark' => '油卡充值：'.$v['amount'].'元，结算价：'.fen2yuan($settlePrice).'元。订单号：'.$subOrderId,
                        'quote_id' => $id,
                        'trade_no' => $subOrderId,
                    ]);
                Db::name('base_supplier')
                    ->where('id', $supplier['id'])
                    ->inc('order_count', 1)
                    ->update();

                $orderAmount += $v['amount'];

                ++$orderNum;

                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();

                if ($orderNum) {
                    return success('成功导入 '.$orderNum.' 个订单，充值总额 '.$orderAmount.' 元。导入失败：'.$e->getMessage());
                } else {
                    return fail('导入失败：'.$e->getMessage());
                }
            }
        }

        return success('成功导入 '.$orderNum.' 个订单，充值总额 '.$orderAmount.' 元');
    }
}
